// System includes
#include <QRect>
#include <QDebug>
#include <QPlastiqueStyle>
#include <QListWidgetItem>
#include <QScrollBar>
#include <QApplication>
#include <QMacStyle>
#include <QToolBar>

// Local includes
#include "yigmainwindow.h"
#include "yig.h"
#include "graphics/yigcolorkit.h"

/////////////////////
// YigOptionsWindow
////////////////////
YigOptionsWindow::YigOptionsWindow(QWidget* mainWindow, QWidget *parent) :
    mMainWindow(mainWindow),
    animationCheckBox("Graphics Animation"),
    audioPipeCheckBox("Send audio via OSC"),
    mAudioPipePort(32254),
    mAudioPipeIP("127.0.0.1"),
    mAudioPiping(false)
{
    setFixedSize(375, 200);
    setWindowTitle("Yig Options");
    setAcceptDrops(false);
    setWindowFlags(Qt::WindowStaysOnTopHint);


    QPlastiqueStyle yigStyle;

    QPalette windowPalette = palette();
    windowPalette.setBrush(QPalette::Window, YigColorKit::background2);
    windowPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    setPalette(windowPalette);

    setStyle(&yigStyle);

    setWindowOpacity(0.8);

    windowPalette = palette();
    windowPalette.setBrush(QPalette::Window, YigColorKit::background2);
    windowPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    animationCheckBox.setPalette(windowPalette);

    animationCheckBox.setStyle(&yigStyle);

    windowPalette = palette();
    windowPalette.setBrush(QPalette::Window, YigColorKit::background2);
    windowPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    audioPipeCheckBox.setPalette(windowPalette);
    audioPipeCheckBox.setStyle(&yigStyle);

    animationCheckBox.setChecked(true);

    pipeIpEntry.setText(mAudioPipeIP);
    pipePortEntry.setMinimum(1);
    pipePortEntry.setMaximum(50000);
    pipePortEntry.setValue(mAudioPipePort);
    audioPipeLayout.addWidget(&audioPipeCheckBox);
    audioPipeLayout.addWidget(&pipeIpEntry);
    audioPipeLayout.addWidget(&pipePortEntry);

    QObject::connect(&animationCheckBox, SIGNAL(toggled(bool)), mMainWindow, SIGNAL(toggleGraphicsAnimation(bool)));
    QObject::connect(&audioPipeCheckBox, SIGNAL(toggled(bool)), this, SLOT(setAudioPipeBool(bool)));
    QObject::connect(&pipePortEntry, SIGNAL(valueChanged(int)), this, SLOT(setAudioPipePort(int)));
    QObject::connect(&pipeIpEntry, SIGNAL(returnPressed()), this, SLOT(setAudioPipeIP()));
    QObject::connect(this, SIGNAL(toggleAudioPipe(bool,QString,int)), mMainWindow, SIGNAL(toggleAudioPipe(bool,QString,int)));

    layout.addWidget(&animationCheckBox);
    layout.addLayout(&audioPipeLayout);
    //layout.addWidget(&audioPipeCheckBox);
    setLayout(&layout);
}

void YigOptionsWindow::setAudioPipeBool(bool pipingAudio)
{
    mAudioPiping = pipingAudio;
    emit toggleAudioPipe(pipingAudio, mAudioPipeIP, mAudioPipePort);
}

void YigOptionsWindow::setAudioPipePort(int audioPipePort)
{
    mAudioPipePort = audioPipePort;
    if(mAudioPiping)
    {
        emit toggleAudioPipe(mAudioPiping, mAudioPipeIP, mAudioPipePort);
    }
}

void YigOptionsWindow::setAudioPipeIP()
{
    mAudioPipeIP = pipeIpEntry.text();
    emit toggleAudioPipe(mAudioPiping, mAudioPipeIP, mAudioPipePort);
}

YigOptionsWindow::~YigOptionsWindow()
{

}

/////////////////
// YigMainWindow
////////////////

YigMainWindow::YigMainWindow(QWidget *parent) :
    QWidget(parent),
    graphicsView(this),
    optionsWindow(0)
{
    setGeometry(QApplication::desktop()->rect());
    setWindowTitle( "Yig, the Father of Serpents" );
    setAcceptDrops(false);
    toolBar = new QWidget();
    toolBar->setGeometry(30, QApplication::desktop()->rect().height()-50, 574, 30);
    toolBar->setWindowFlags( Qt::CustomizeWindowHint | Qt::Tool);
    bootStatus = new QLabel(toolBar);
    numberOfSynths = new QLabel(toolBar);
    avgCPU = new QLabel(toolBar);
    peakCPU = new QLabel(toolBar);
    recordButton = new QToolButton(toolBar);
    connectButton = new QToolButton(toolBar);
    optionsButton = new QToolButton(toolBar);
    QPlastiqueStyle yigStyle;

    /*
    QLinearGradient gradient(0, 0, 0, 100);
    gradient.setColorAt(0.0, QColor(80, 80, 80));
    gradient.setColorAt(0.05, QColor(80, 80, 80));
    gradient.setColorAt(0.2, QColor(44, 44, 44));
    gradient.setInterpolationMode(QGradient::ColorInterpolation);
    QBrush backgroundBrush(gradient);*/
    //backgroundBrush.setStyle(Qt::LinearGradientPattern);
    backgroundBrush = YigColorKit::background2;
    toolBar->setWindowOpacity(0.8);

    QPalette windowPalette = toolBar->palette();
    windowPalette.setBrush(QPalette::Window, backgroundBrush);
    windowPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    toolBar->setPalette(windowPalette);
    toolBar->setStyle(&yigStyle);

    windowPalette = palette();
    windowPalette.setBrush(QPalette::Window, YigColorKit::focus1);
    windowPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    setPalette(windowPalette);
    setStyle(&yigStyle);

    QPalette dockPalette = dock.palette();
    dockPalette.setBrush(QPalette::Window, backgroundBrush);
    dockPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    dock.setPalette(dockPalette);
    dock.setStyle(new QMacStyle);

    QPalette labelPalette;

    QFont serverFont("monaco", 12);
    labelPalette = bootStatus->palette();
    labelPalette.setColor(QPalette::WindowText, YigColorKit::focus1);
    labelPalette.setColor(QPalette::Text, YigColorKit::focus1);
    labelPalette.setColor(QPalette::Background, YigColorKit::focus2Highlight);
    bootStatus->setPalette(labelPalette);
    bootStatus->setStyle(&yigStyle);
    bootStatus->setFont(serverFont);
    bootStatus->setGeometry(QRect(5, 2, 110, 25));
    //bootStatus->setFrameStyle(QFrame::StyledPanel);
    bootStatus->setTextFormat(Qt::RichText);
    bootStatus->setText("server inactive");

    QFont labelFont("monaco", 10);
    labelPalette.setColor(QPalette::WindowText, YigColorKit::background2);
    labelPalette = numberOfSynths->palette();
    labelPalette.setColor(QPalette::Text, YigColorKit::focus1);
    numberOfSynths->setPalette(labelPalette);
    numberOfSynths->setGeometry(QRect(120, 2, 90, 25));
    numberOfSynths->setStyle(&yigStyle);
    numberOfSynths->setFont(labelFont);
    numberOfSynths->setText(" synths: ");
    //numberOfSynths->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);

    labelPalette = avgCPU->palette();
    labelPalette.setColor(QPalette::Text, YigColorKit::focus1);
    avgCPU->setPalette(labelPalette);
    avgCPU->setGeometry(QRect(215, 2, 100, 25));
    avgCPU->setStyle(&yigStyle);
    avgCPU->setFont(labelFont);
    avgCPU->setText(" avg cpu: ");
    //avgCPU->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);

    labelPalette = peakCPU->palette();
    labelPalette.setColor(QPalette::Text, YigColorKit::focus1);
    peakCPU->setPalette(labelPalette);
    peakCPU->setGeometry(QRect(320, 2, 105, 25));
    peakCPU->setStyle(&yigStyle);
    peakCPU->setFont(labelFont);
    peakCPU->setText(" peak cpu: ");
    //peakCPU->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);

    recordButton->setGeometry(430, 2, 50, 25);
    recordButton->setText("record");
    recordButton->setStyleSheet("QToolButton{ background: #222; color: #ddd; border-radius: 0px}"
                                "QToolButton::checked{ background: #bbb; color: #000; }"
                                "QToolButton::hover{ background: #bbb; color: #000; }");
    recordButton->setCheckable(true);
    QObject::connect(recordButton, SIGNAL(clicked()), this, SLOT(record()));

    connectButton->setGeometry(482, 2, 62, 25);
    connectButton->setText("connect");
    connectButton->setStyleSheet("QToolButton{ background: #222; color: #ddd; border-radius: 0px}"
                                "QToolButton::checked{ background: #bbb; color: #000; }"
                                "QToolButton::hover{ background: #bbb; color: #000; }");
    connectButton->setCheckable(true);
    QObject::connect(connectButton, SIGNAL(clicked()), this, SLOT(networkConnection()));

    optionsButton->setGeometry(546, 2, 25, 25);
    optionsButton->setText("+");
    optionsButton->setStyleSheet("QToolButton{ background: #222; color: #ddd; border-radius: 0px}"
                                "QToolButton::checked{ background: #bbb; color: #000; }"
                                "QToolButton::hover{ background: #bbb; color: #000; }");
    optionsButton->setCheckable(true);
    QObject::connect(optionsButton, SIGNAL(clicked()), this, SLOT(toggleOptionsWindow()));

    /*
    // Populate the channelArray with initialized YigNetworkChannels
    for(int i = 0; i < Yig::NUMBER_OF_NETWORK_CHANNELS; i++)
    {
        YigNetworkChannelView* channelView = new YigNetworkChannelView(&glWidget, this);
        channelView->setGeometry(QRect(0, 0,this->width(),this->height()));
        setCentralWidget(channelView);
        channelViewList.append(channelView);
    }*/
    graphicsView.setGeometry(0, 0, width(), height() - 45);
    //setCentralWidget(&graphicsView);
    //setOnline(online);

    //addToolBar(Qt::TopToolBarArea, toolBar);
    //toolBar->setAllowedAreas(Qt::TopToolBarArea);
    //toolBar->setFloatable(false);
    //toolBar->setMovable(false);
    //dock.setFeatures(QDockWidget::NoDockWidgetFeatures);
    //dock.setWidget(toolBar);
    //dock.setFixedHeight(30);
    //addDockWidget(Qt::TopDockWidgetArea, &dock);
    showMaximized();
    mOnline = false;
    networkConnection();
    toolBar->show();
    toolBar->raise();
    //show();
}

YigMainWindow::~YigMainWindow()
{
    /*
    while(!channelViewList.isEmpty())
    {
        delete channelViewList.takeFirst();
    }
    channelViewList.clear();*/

    if(optionsWindow)
    {
        optionsWindow->close();
        delete optionsWindow;
        optionsWindow = 0;
    }

    delete toolBar;
}

void YigMainWindow::setActiveChannel(int channelNum)
{
    /*
    int bottomViewCounter = 0;
    // Set Active status
    for(int i = 0; i < Yig::NUMBER_OF_NETWORK_CHANNELS; i++)
    {
        bottomViewCounter++;
        if(i == channelNum)
        {
            channelViewList.at(i)->setActiveView(true);
        }
        else
        {
            channelViewList.at(i)->setActiveView(false);
            channelViewList.at(i)->lower();
        }
    }
    channelViewList[channelNum]->raise();*/
}
/*
void YigMainWindow::setOnline(bool online)
{
    mOnline = online;
    if(mOnline)
    {

    }
}
*/
void YigMainWindow::updateServerStatus(QString serverBootStatus, int numSynths, float avgCPU, float peakCPU)
{
    bootStatus->setText("server <span style=\" font-size:12pt; font-weight:600; color:#666666;\">"+serverBootStatus+"</span>");
    numberOfSynths->setText(" synths: " + QString::number(numSynths));
    this->avgCPU->setText(" avg cpu: "+QString::number(avgCPU, 'f', 1)+"%");
    this->peakCPU->setText(" peak cpu: "+QString::number(avgCPU, 'f', 1)+"%");
}

void YigMainWindow::addUser(QString userName)
{
    qDebug() << "ADD USER: " << userName;
    if(mOnline)
    {
        qDebug() << "ADD USER: " << userName;
        currentUsers->insertItem(0, userName);
    }
}

void YigMainWindow::removeUser(QString userName)
{
    if(mOnline)
    {
        QList<QListWidgetItem*> list = currentUsers->findItems(userName,Qt::MatchCaseSensitive);
        for (int i = 0; i < list.size(); ++i) {
            delete list.at(i);
        };
    }
}

YigNetworkChannelView* YigMainWindow::getGraphicsView()
{
    return &graphicsView;
}
void YigMainWindow::resizeEvent(QResizeEvent *e)
{
    graphicsView.resize(e->size());
    // Call the base method
    QWidget::resizeEvent(e);

    //emit signalResize(e);
}

void YigMainWindow::record()
{
    if(recordButton->isChecked())
    {
        recordButton->setText("stop");
    }

    else
    {
        recordButton->setText("record");
    }

    emit recording(recordButton->isChecked());
}

void YigMainWindow::networkConnection()
{
    if(connectButton->isChecked())
    {
        toolBar->setGeometry(30, QApplication::desktop()->rect().height() - 80, 574, 60);
        currentUsers = new QListWidget(toolBar);
        currentUsers->setFlow(QListWidget::LeftToRight);
        currentUsers->setWrapping(true);
        currentUsers->setGeometry(55, 33, 514, 19);
        currentUsers->setStyleSheet("QListWidget{ background: #000; color: #ddd; border: 1px solid #111; }");
        currentUsers->setFocusPolicy(Qt::NoFocus);
        currentUsers->verticalScrollBar()->setGeometry(currentUsers->geometry().width()-20, 0, 20, 10);
        currentUsers->horizontalScrollBar()->setDisabled(true);
        //currentUsers->horizontalScrollBar()->setGeometry(0, 20, currentUsers->geometry().width(), 5);
        currentUsersLabel = new QLabel(toolBar);
        currentUsersLabel->setGeometry(10, 31, 60, 22);
        QPalette labelPalette = currentUsersLabel->palette();
        labelPalette.setColor(QPalette::All, QPalette::WindowText, YigColorKit::focus1);
        currentUsersLabel->setPalette(labelPalette);
        currentUsersLabel->setText("Users: ");
        connectButton->setText("disconnect");
        qDebug() << "WE ARE ONLINE";
        mOnline = true;
        currentUsers->show();
        currentUsersLabel->show();
    }

    else
    {
        if(mOnline)
        {
            if(currentUsers->isVisible())
                currentUsers->close();
            delete currentUsers;
            toolBar->setGeometry(30, QApplication::desktop()->rect().height()- 50, 574, 30);
        }
        mOnline = false;
        qDebug() << "WE ARE OFFLINE";
        connectButton->setText("connect");
    }

    emit networking(connectButton->isChecked());
}

void YigMainWindow::toggleOptionsWindow()
{
    if(optionsButton->isChecked())
    {
        // open window
        optionsWindow = new YigOptionsWindow(this);
        //QObject::connect(optionsWindow, SIGNAL(destroyed()), this, SLOT(toggleOptionsWindow()));
        optionsWindow->move((QApplication::desktop()->rect().width()/2) - (optionsWindow->geometry().width()/2),
                            (QApplication::desktop()->rect().height()/2) - (optionsWindow->geometry().height()/2));
        optionsWindow->show();
    }

    else
    {
        // Close window
        if(optionsWindow)
        {
            optionsWindow->close();
            delete optionsWindow;
            optionsWindow = 0;
        }
    }
}
